// import 'dart:ffi';

import 'dart:ffi';
import 'dart:io';
import 'dart:convert';

void main() {
    var var_string = '变量';
    var new_string = "Dart 使用 \${var_string} 进行 ${var_string} 连接"; 
    print(var_string);
    print(new_string);
    // Type var_type = var_string.runtimeType;
    String var_type = var_string.runtimeType.toString();
    // print(var_type.runtimeType);
    print(var_type);
    int number = 1;
    print(number);
    print(number.runtimeType.toString());
    double number_double = 1.001;
    print(number_double); // 1
    print(number_double.runtimeType.toString()); // int
    bool var_bool = true;
    print(var_bool); // true
    print(var_bool.runtimeType.toString()); // bool
    // String var_string = 'string';
    String heredoc = r"""
\${var_string} = ${var_string}""";
    print(heredoc);
    String nowdoc = r'''
\${var_string} = ${var_string}
''';
    print(nowdoc);
    var var_record = ('first', second: 2, 3, false, last:'true');
    print(var_record); // (first, 3, false, last: true, second: 2)
    print(var_record.runtimeType.toString()); // (String, int, bool, {String last, int second})
    print(var_record.$1);
    print(var_record.last);
    (String, int, bool, {String last, int second}) record1 = ('a', 2, false, last:'c', second:4);
    print(record1.runtimeType);

    Record var_record1 = ('first', second: 2, 3, false, last:true);
    print(var_record1.runtimeType);

    (String, int) string_int = ('年份', 2023);
    print(string_int); // first

    var record_1 = (1,2);
    var record_2 = (1,1);

    bool result;
    result = (record_1 == record_2) ? true : false;
    print(result);

    var record_3 = (first:1, second:2);
    var record_4 = (second:2, first:1);

    result = (record_3 == record_4) ? true : false;
    print(result);

    var list = [1, 2, 3];
    print(list.runtimeType.toString()); // List<int>
    print(list); // [1, 2, 3]
    print(list[0]); // 1

    var list_string = ['a', 'b', 'c'];
    print(list_string.runtimeType.toString()); // List<String>
    print(list_string[0]); // a

    // List var_list = [0,1,2];
    List var_list = ['a', 'b', 'c'];
    print(var_list.runtimeType.toString()); // List<dynamic>

    List<int> list_int = [1, 2, 3];
    print(list_int.runtimeType.toString()); // List<int>

    var var_int_string = [1, 'a'];
    print(var_int_string.runtimeType.toString()); // List<Object>
    print(var_int_string); // [1, a]
    print(var_int_string[0]); // 1

    List list_int_string = [1, 'a'];
    print(list_int_string.runtimeType.toString()); // List<dynamic>
    print(list_int_string); // [1, a]
    print(list_int_string[0]); // 1

    List<dynamic> int_dynamic = [1, 2, 3];
    print(int_dynamic.runtimeType.toString()); // List<dynamic>
    print(int_dynamic); // [1, 2, 3]
    print(int_dynamic[0]); // 1

    List<dynamic> string_dynamic = ['a', 'b', 'b'];
    // List<dynamic> string_dynamic = [1, 2, 3];
    print(string_dynamic.runtimeType.toString()); // List<dynamic>
    print(string_dynamic); // [a, b, b]
    print(string_dynamic[0]); // a

    List<dynamic> int_string_dynamic = [1, 'a'];
    print(int_string_dynamic.runtimeType.toString()); // List<dynamic>
    print(int_string_dynamic); // [1, a]
    print(int_string_dynamic[0]); // 1

    List<Object> int_Object = [1, 2, 3];
    print(int_Object.runtimeType.toString()); // List<Object>
    print(int_Object); // [1, 2, 3]
    print(int_Object[0]); // 1

    List<Object> string_Object = ['a', 'b', 'b'];
    // List<Object> string_Object = [1, 2, 3];
    print(string_Object.runtimeType.toString()); // List<Object>
    print(string_Object); // [a, b, b]
    print(string_Object[0]); // a

    List<Object> int_string_Object = [1, 'a'];
    print(int_string_Object.runtimeType.toString()); // List<Object>
    print(int_string_Object); // [1, a]
    print(int_string_Object[0]); // 1

    var set = {1, 2};
    print(set); // {1, 2}
    print(set.runtimeType.toString()); // _Set<int>

    Set<int> set_int = {1, 2};
    print(set_int); // {1, 2}
    print(set_int.runtimeType.toString()); // _Set<int>

    var var_set_string = {'a', 'b'};
    print(var_set_string); // {1, 2}
    print(var_set_string.runtimeType.toString()); // _Set<String>

    Set<String> set_string = {'a', 'b'};
    print(set_string); // {'a', 'b'}
    print(set_string.runtimeType.toString()); // _Set<String>

    var var_set_int_string = {1, 'a'};
    print(var_set_int_string); // {1, a}
    print(var_set_int_string.runtimeType.toString()); // _Set<Object>

    Set<Object> set_object_int = {1, 2};
    print(set_object_int); // {1, 2}
    print(set_object_int.runtimeType.toString()); // _Set<Object>

    Set<Object> set_object_string = {'a', 'b'};
    print(set_object_string); // {'a', 'b'}
    print(set_object_string.runtimeType.toString()); // _Set<Object>

    Set<Object> set_object_int_string = {1, 'a'};
    print(set_object_int_string); // {1, 'a'}
    print(set_object_int_string.runtimeType.toString()); // _Set<Object>

     // 声明集合必须指定类型，即使元素为多种类型，也需要用 Object 修饰，否则会被认定为 Map 数据类型，影响后续操作
    var set_default_int = <int>{};
    // Set<int> set_default_int = {};
    set_default_int.add(1);
    set_default_int.addAll({1, 2});
    print(set_default_int); // {1, 2}

    Set<Object> set_default_string = {'a'};
    set_default_string.add(1);
    set_default_string.addAll({'b', 2});
    print(set_default_string); // {a, 1, b, 2}

    // 检查元素是否在集合中
    var is_in_set = set_default_string.contains('a');
    print(is_in_set); // true
    bool is_all_in_set = set_default_string.containsAll({'b', 2});
    print(is_all_in_set); // true
   
   var map = {};
   map['first'] = 1;
   print(map); // {first: 1}
   print(map.runtimeType.toString()); // _Map<dynamic, dynamic>
   print(map['first']); // 1

   var map_int_string = <int, String>{1:'first'};
   print(map_int_string); // {1: first}
   print(map_int_string.runtimeType.toString()); // _Map<int, String>
   print(map_int_string[1]); // first

   Map<dynamic, dynamic> map_dynamic = {1:1};
   print(map_dynamic.runtimeType.toString()); // _Map<dynamic, dynamic>

    Map<Object, Object> map_object = {1:1};
   print(map_object.runtimeType.toString()); // _Map<Object, Object>

    // 实例化一个 人类
    Man man = new Man(18, 'Alice');
    print(man.name); // Alice
    man.getAge(); // 18
    man.setAge(20);
    man.getAge(); // 20
    man._setName('Bob'); // 没有做成模块，随意可以访问
    print(man.name); // Bob
    print(man.runtimeType.toString()); // Man
    // 获取器
    man.age2 = 1;
    print(man.age);
    print(man.name);
    print(man.age2);
    // 如果没有事先定义属性，则必须通过设置器来声明属性
    man.age = 4;

    var symbol_1 = Symbol('string');
    var symbol_2 = Symbol('string');
    result = symbol_1 == symbol_2 ? true : false;
    print(result); // true
    print(identical(symbol_1,symbol_2)); // false

    // 特殊字符 与 Unicode 唯一位点码 互相转换
    String smile = '😊';
    Runes smile_string_to_runes = smile.runes;
    String smile_runes_to_string = new String.fromCharCodes(smile_string_to_runes);
    print(smile); // 😊
    print(smile_string_to_runes); // (128522)
    print(smile_string_to_runes.runtimeType); // Runes
    print(smile_runes_to_string); // 😊

    // 整数 -> 浮点数
    print('## 1.');
    print(1.toDouble()); // 1.0
    // 整数 -> 布尔
    print('## 2.');
    print(1 != 0); // true
    // 整数 -> 字符串
    print('## 3.');
    print(1.toString()); // '1'
    // 浮点数 -> 整数
    print('## 4.');
    double var_double = 1.1;
    print(var_double.toInt()); // 1
    // 浮点数 -> 布尔
    print('## 5.');
    print(1.1 != 0.0); // true
    // 浮点数 -> 字符串
    print('## 6.');
    print(1.1.toString()); // '1.1'
    print(1.1.toString().runtimeType); // String
    // 字符串 -> 整数
    print('## 7.');
    print(int.parse('111')); // 111
    print(int.parse('111').runtimeType); // int
    // 非纯数字字符串转化为整数需要额外操作，没有直接的语法糖
    // 字符串 -> 浮点数
    print('## 8.');
    print(double.parse('1.1')); // 1.1
    print(double.parse('1.1').runtimeType); // double
    // 非纯数字字符串转化为浮点数需要额外操作，没有直接的语法糖
    // 字符串 -> 布尔
    print('## 9.');
    print(bool.parse('true')); // true
    print(bool.parse('true').runtimeType); // bool
    print(bool.parse('false')); // false
    print(bool.parse('false').runtimeType); // bool

    // 布尔 -> 整数
    print('## 10.');
    var_bool = true;
    // ignore: dead_code
    print( var_bool ? 1 : 0 );
    // ignore: dead_code
    print( false ? 1 : 0 );
    // 布尔 -> 浮点数
    print('## 11.');
    // ignore: dead_code
    print( var_bool ? 1.0 : 0.0 ); // 1.0
    // ignore: dead_code
    print( false ? 1.0 : 0.0 ); // 0.0
    // ignore: dead_code
    print( (false ? 1.0 : 0.0).runtimeType ); // double
    // 布尔 -> 字符串
    print('## 12.');
    print( true.toString() ); // 'true'
    print( false.toString() ); // 'false'
    print( false.toString().runtimeType ); // String

    var map_to = {'key1':'value',1:1};
    var array_result = [...map_to.values];
    print(array_result); // [value, 1]

    if(array_result[0] == 'value'){
      print('if 语句');
    }else if(array_result[1] == 1){
      print('else if 语句');
    }else{
      print('else 语句');
    }

    var while_num = 10;
    var current_num = 1;
    while(current_num <= while_num){
      print(current_num);
      current_num++;
    }

    for(var for_i = 1; for_i <= 10; for_i++){
        if(for_i == 5){
          continue;
        }
        print(for_i);
        if(for_i == 9){
          break;
        }
        
    }

    echo(123);

    const double pi = 3.14;
    const List<int> numbers = [1, 2, 3, 4, 5];
    print(numbers.runtimeType);
    print(numbers);

    final e;
    e = 2.71828;
    print(e); // 2.71828
    print( e.runtimeType ); // double

    try {
        throwException();
    } catch (e) {
        print("捕获到异常1: ${e}");
    }


    // 获取当前脚本的 Uri  
    Uri script_uri = Platform.script;  

    // 从 Uri 创建文件对象
    File script_file = File(script_uri.toFilePath());

    // 获取脚本文件所在的目录
    Directory script_dir = script_file.parent;

    // 获取脚本文件所在目录的路径  
    String script_dir_path = script_dir.path;

    String test_txt = script_dir_path + '/test_txt.txt';
    
    // 使用 File 类创建一个新文件
    File file = File(test_txt);

    // 如果文件不存在，则创建它  
    if (!file.existsSync()) {
      file.createSync(); // 创建文件
    }
    // 创建文件
    // 读取文件
    // file.readAsString().then((String contents) {
    //   print(contents);
    // });
    // 第二种方法
    // getContents(test_txt);

    // 写入文件
    String contents = '文件内容';
    file.writeAsString(contents);
    // 异步-文件追加内容
    file.writeAsString(contents, mode: FileMode.append);
    // 同步-文件追加内容
    file.writeAsStringSync(contents, mode: FileMode.append);

    // 删除文件
    // file.delete();
    // 读取目录
    Directory directory = Directory(script_dir_path);  
    // 迭代文件
    List<FileSystemEntity> entities = directory.listSync();
    for ( FileSystemEntity entity in entities ) {
        print(entity.path);
    }

    // 获取文件扩展名
    // print(file.path.lastIndexOf('.'));

    // var file_extension = file.path.substring(file.path.lastIndexOf('.') + 1);
    // print(file_extension);
    print(getExtension(file));

    // 获取文件大小
    print( File(test_txt).statSync().size);
    print( file.statSync().size);
    print( file.lengthSync() );
    // print( File(test_txt).length() ); // 需要异步操作

    FileStat file_status = file.statSync();  
    print( file_status.runtimeType );
    print( file_status );
    // 文件可访问性
    print( file_status.mode );
    // 文件类型
    print( file_status.type );
    // 修改时间
    print( file_status.modified );
    // 访问时间
    print( file_status.accessed );
    // 文件创建时间
    // dart 中不支持获取文件的创建时间，终端：MacOS
    // 文件全路径
    print( file.path );
    // 文件名称
    print(  file.path.substring(file.path.lastIndexOf('/') + 1, file.path.lastIndexOf('.')) );
    // 目录操作
    var is_file = FileSystemEntity.isFileSync('test_txt');
    var is_dir = FileSystemEntity.isDirectorySync(test_txt);
    print( is_file );
    print( is_dir );

    String test_path = '/Users/zhang/文档/Gitee/dart/test_path';
    Directory test_directory = Directory(test_path);

    if( !test_directory.existsSync() ){
        test_directory.create();
    }
    // 目录信息
    print( Directory(test_path).statSync() ); // -1 不存在
    print( Directory(test_path).statSync().size ); // -1 不存在
    // 删除目录
    test_directory.delete();

}

String getExtension(File file){
  return file.path.substring(file.path.lastIndexOf('.') + 1);
}

void getContents(file_path) async {
    File file = File(file_path);
    // 如果文件不存在，则创建它
    if (!file.existsSync()) {
      file.createSync(); // 创建文件
    }
    var contents = await file.readAsString();
    print(contents);
}

void throwException() {
  // String a = 1;
  throw '这是一个异常';  
}

void echo(var string){
  print(string);
}

/**
 * --------------------------------
 * # 人类
 * --------------------------------
 * 1. 年龄
 * 2. 姓名
 * 3. 构造：年龄、姓名
 * --------------------------------
 */
class Man
{
    // 定义静态属性
    static String from = 'earth';
    // _ 定义私有属性
    int? _age;
    // 定义普通属性
    String? name;
    // 构造方法
    Man(int age, String name)
    {
        this._age = age;
        this._setName(name);
    }
    // 普通方法
    void getAge()
    {
        print(this._age);
    }
    void setAge(int age)
    {
        this._age = age;
    }
    // 私有方法：关键备注：私有方法的类需要放到单独的文件中，通过 import 引入，才能达到私有的效果
    void _setName(String name)
    {
        this.name = name;
    }
    // 获取器
    int get age{
        print('获取器');
        this.name = 'sss';
        return this._age!.toInt();
    }

    int get age2{
        return this._age!.toInt();
    }

    void set age2(value){
        this._age!.toInt();
    }
    // 设置器
    void set age(int value){
        this.age2 = value;
        print('设置器：输出 ' +  value.toString());
    }
}

class Child extends Man
{
  Child(super.age, super.name);
}
